
#ifndef RGraphicsResource_h
#define RGraphicsResource_h

#include <Defines.h>
#include <CSharpGarbagePointer.h>
#include <CSharpPropertyMethods.h>

#include <System/IDisposable.h>
#include <System/Object.h>
#include <System/Collections/Generic/List.h>
#include <System/WeakReference.h>
#include <System/Generic/EventHandler.h>
#include <System/EventArgs.h>
#include <REvents.h>

namespace Riccsson
{
	namespace Xna
	{
		namespace Framework
		{
			namespace Graphics
			{	
				// Forward declerations.
				class GraphicsDevice;

				class GraphicsResource
					: public Riccsson::System::Object
					, public Riccsson::System::IDisposable
				{
					private: bool disposed;
        
					// Resources may be added to and removed from the list from many threads.
					private: static GC_PTR<Riccsson::System::object> resourcesLock;

					// Use WeakReference for the global resources list as we do not know when a resource
					// may be disposed and collected. We do not want to prevent a resource from being
					// collected by holding a strong reference to it in this list.
					private: static Riccsson::System::Collections::Generic::List<GC_PTR<Riccsson::System::WeakReference>> resources;

					// The GraphicsDevice property should only be accessed in Dispose(bool) if the disposing
					// parameter is true. If disposing is false, the GraphicsDevice may or may not be
					// disposed yet.
					public: GC_PTR<GraphicsDevice> _graphicsDevice;

							
					PROP3(GraphicsResource, GC_PTR<GraphicsDevice>, graphicsDevice)
					PROP3(GraphicsResource, bool, IsDisposed)
							
					public: PROP3_GET(GC_PTR<GraphicsDevice>, graphicsDevice)
					{
						return _graphicsDevice;
					}
					public: /*internal*/ PROP3_SET(GC_PTR<GraphicsDevice>, graphicsDevice)
					{
						_graphicsDevice = value;
					}
					
					public: PROP3_GET(bool, IsDisposed)
					{
						return disposed;
					}
					public: PROP3_SET(bool, IsDisposed){throw;}
					
					public: GC_PTR<Riccsson::System::string> Name; // { get; set; }
					
					public: GC_PTR<Riccsson::System::Object> Tag; // { get; set; }
							
					COPY_CONSTRUCTOR(GraphicsResource)
					{
						PROP3_INIT_COPY(GraphicsResource, GC_PTR<GraphicsDevice>, graphicsDevice);
						PROP3_INIT_COPY(GraphicsResource, bool, IsDisposed);
					}

					public: /*internal*/ GraphicsResource()
						: PROP3_INIT(GraphicsResource, graphicsDevice)
						, PROP3_INIT(GraphicsResource, IsDisposed)
					{
						//resourcesLock = new Riccsson::System::object();

						//lock (resourcesLock)
						//{
						//	resources.Add(new Riccsson::System::WeakReference(this));
						//}
					}

					~GraphicsResource()
					{
						// Pass false so the managed objects are not released
						Dispose(false);
					}

					/// <summary>
					/// Called before the device is reset. Allows graphics resources to 
					/// invalidate their state so they can be recreated after the device reset.
					/// Warning: This may be called after a call to Dispose() up until
					/// the resource is garbage collected.
					/// </summary>
					/*internal*/ protected: virtual void GraphicsDeviceResetting()
					{

					}

					public: /*internal*/ static void DoGraphicsDeviceResetting()
					{

					}

					/// <summary>
					/// Dispose all graphics resources remaining in the global resources list.
					/// </summary>
					private: /*internal*/ static void DisposeAll()
					{

					}

					public: void Dispose()
					{
						// Dispose of managed objects as well
						Dispose(true);
						// Since we have been manually disposed, do not call the finalizer on this object
						//GC.SuppressFinalize(this);
						throw;
					}
		
					/// <summary>
					/// The method that derived classes should override to implement disposing of managed and native resources.
					/// </summary>
					/// <param name="disposing">True if managed objects should be disposed.</param>
					/// <remarks>Native resources should always be released regardless of the value of the disposing parameter.</remarks>
					protected: virtual void Dispose(bool disposing)
					{

					}

					public: event<Void, Riccsson::System::Generic::EventHandler<Riccsson::System::EventArgs>> Disposing;
		
				};
			}
		}
	}
}

#endif
